import _ from 'lodash';
import {message} from 'antd';
import * as moment from 'moment';
import {observable, action, computed} from 'mobx';
import {AdBean, AdBindBean, AdSearchBean, AdService} from '../../../model/ad/Ad';
import {AdAppPositionController} from '../../../model/ad/adPosition/AdAppPositionController';
import {treeFormatNode, urlValid, textLengthValid, timeValid, toPlainObjectDeep, loadArea} from '../../../utils/Utils';
import {FormStore, ListStore, FieldItem, isRequired, isSelectRequired, toJSDeep} from '../../common/store/Store';

const adService = new AdService();
const adAppPositionController = new AdAppPositionController();

export const mediaTypeToContent = {
    '0': 'imageUrl',
    '1': 'contentTypeUrl',
    '2': 'richText',
    '3': 'text',
}

export const mediaTypeToText = {
    '0': '上传图片',
    '1': '外部图片',
    '2': '富文本',
    '3': '纯文本',
}

interface AdDto<T> extends AdBean<FieldItem> {
    time?: any | T;
    imageUrl?: string | T;
    text?: string | T;
    richText?: string | T;
    contentTypeUrl?: string | T;
    apiUrl?: Array<string> | T;
    filterAreaIds?: Array<string> | T;
}

export class AdField implements AdDto<FieldItem> {
    constructor(type = 'add') {
        if (type === 'edit') {
            _.forEach(this, (field: FieldItem, key: string) => {
                if (field.hasFeedback === true) {
                    field.validateStatus = 'success';
                }
            })
        }
    }

    id: FieldItem = new FieldItem({
        value: null
    });
    areaIds: FieldItem = new FieldItem({
        value: [],
        hasFeedback: true,
        required: true
    });
    filterAreaIds: FieldItem = new FieldItem({
        value: []
    });
    title: FieldItem = new FieldItem({
        value: '',
        hasFeedback: true,
        required: true
    });
    orders: FieldItem = new FieldItem({
        value: undefined
    });
    beginDate: FieldItem = new FieldItem({
        value: null,
        hasFeedback: true,
        required: true
    });
    endDate: FieldItem = new FieldItem({
        value: null,
        hasFeedback: true,
        required: true
    });
    url: FieldItem = new FieldItem({
        value: ''
    });
    tags: FieldItem = new FieldItem({
        value: [],
        option: []
    });
    // businessUnitId: FieldItem = new FieldItem({
    //     value: -1,
    //     hasFeedback: true,
    //     required: true,
    //     disabled:false,
    //     option:[{
    //         id: -1,
    //         name: '请选择',
    //         title:'请选择',
    //         description:'请选择'
    //     }]
    // });
    // businessUnitName: FieldItem = new FieldItem({
    //     value: ''
    // });
    // businessUnitTitle: FieldItem = new FieldItem({
    //     value: ''
    // });
    // appId: FieldItem = new FieldItem({
    //     value: -1,
    //     hasFeedback: true,
    //     required: true,
    //     disabled:true,
    //     option:[{
    //         id: -1,
    //         name: '请选择',
    //         title:'请选择',
    //         description:'请选择'
    //     }]
    // });
    // appName: FieldItem = new FieldItem({
    //     value: ''
    // });
    // appTitle: FieldItem = new FieldItem({
    //     value: ''
    // });
    // platform: FieldItem = new FieldItem({
    //     value: -1,
    //     hasFeedback: true,
    //     required: true,
    //     disabled:true,
    //     option:[{
    //         type: -1,
    //         name: '请选择',
    //         title:'请选择',
    //         description:'请选择'
    //     }]
    // });
    // platformName: FieldItem = new FieldItem({
    //     value: ''
    // });
    // platformTitle: FieldItem = new FieldItem({
    //     value: ''
    // });
    // page: FieldItem = new FieldItem({
    //     value: -1,
    //     hasFeedback: true,
    //     required: true,
    //     disabled:true,
    //     option:[{
    //         id: -1,
    //         name: '请选择',
    //         title:'请选择',
    //         description:'请选择'
    //     }]
    // });
    // pageName: FieldItem = new FieldItem({
    //     value: ''
    // });
    // pageTitle: FieldItem = new FieldItem({
    //     value: ''
    // });
    // position: FieldItem = new FieldItem({
    //     value: -1,
    //     hasFeedback: true,
    //     required: true,
    //     disabled:true,
    //     option:[{
    //         id: -1,
    //         name: '请选择',
    //         title:'请选择',
    //         description:'请选择'
    //     }]
    // });
    // positionName: FieldItem = new FieldItem({
    //     value: ''
    // });
    // positionTitle: FieldItem = new FieldItem({
    //     value: ''
    // });
    mediaType: FieldItem = new FieldItem({
        value: -1,
        hasFeedback: true,
        required: true,
        disabled: false,
        option: [{
            id: -1,
            type: -1,
            name: '请选择',
        }]
    });
    content: FieldItem = new FieldItem({
        value: ''
    });
    contentUrl: FieldItem = new FieldItem({
        value: ''
    });
    imageUrl: FieldItem = new FieldItem({
        value: '',
        hasFeedback: true,
        required: true,
        ignore: true
    });
    text: FieldItem = new FieldItem({
        value: ''
    });
    richText: FieldItem = new FieldItem({
        value: '',
        hasFeedback: true,
        required: true,
        ignore: true
    });
    contentTypeUrl: FieldItem = new FieldItem({
        value: '',
        hasFeedback: true,
        required: true,
        ignore: true
    });
    time: FieldItem = new FieldItem({
        value: null,
        hasFeedback: true,
        required: true
    });
    apiUrl: FieldItem = new FieldItem({
        value: []
    });
}

class AdSearchField implements AdSearchBean<FieldItem> {
    title: FieldItem = new FieldItem({
        value: ''
    });
    // beginDate: FieldItem = new FieldItem({
    //     value: null
    // });
    // endDate: FieldItem = new FieldItem({
    //     value: null
    // });
}

class AdBindMediaTypeField implements AdBindBean<FieldItem> {
    id: FieldItem = new FieldItem({
        value: null
    });
    adPositionIds: FieldItem = new FieldItem({
        value: [],
        hasFeedback: true,
        required: true,
        option: []
    });
    title: FieldItem = new FieldItem({
        value: '',
        disabled: true
    });
    mediaType: FieldItem = new FieldItem({
        value: '',
        disabled: true
    })
}

const addDefaultFields = toPlainObjectDeep(new AdField());
const editDefaultFields = toPlainObjectDeep(new AdField('edit'));

export class AdBaseFormStore extends FormStore<AdField, AdDto<any>> {
    @observable confirmLoading: boolean = false;

    @action
    changeConfirmLoading(params) {
        this.confirmLoading = params;
    }

    validators = {
        // businessUnitId: [isSelectRequired],
        // appId: [isSelectRequired],
        // platform: [isSelectRequired],
        // page: [isSelectRequired],
        // position: [isSelectRequired],
        mediaType: [isSelectRequired],
        imageUrl: [isRequired],
        richText: [isRequired],
        text: [textLengthValid(200)],
        contentTypeUrl: [isRequired, urlValid, textLengthValid(150)],
        time: [isRequired, timeValid],
        url: [urlValid, textLengthValid(150)],
        title: [isRequired, textLengthValid(50)],
        areaIds: [isRequired],
    };

    /*=========================获取api======================*/
    @action
    getAdapiUrlById(params) {
        return adService.getAdapiUrlById(params).then((data) => {
            if (data.success) {
                this.changeField("apiUrl", {value: data.result});
            }
        })
    }

    @action
    findTags() {
        return adService.findTags()
            .then(action((data: any) => {
                this.fields.tags.option = data.result;
            }));
    }

    /*==================获取类型api==========================*/
    @action
    getMediaType() {
        return adAppPositionController
            .getAllMediaType()
            .then((data) => {
                this.fields.mediaType.option = _.cloneDeep(toJSDeep(this.fields.mediaType.option)).concat(data.result);
                return data;
            });
    }

    @action
    selectmediatype(value) {
        this.changeFields(_.mapValues(_.invert(mediaTypeToContent), () => {
            return {ignore: true, value: ''}
        }));

        this.changeField(mediaTypeToContent[value], {ignore: false});
        this.valid(mediaTypeToContent[value], '', !this.fields[mediaTypeToContent[value]].required);
    }

    // @action getBu(partnerId = null){
    //     return adAppPositionController
    //         .getPartnerBu({partnerId: partnerId})
    //         .then((data)=>{
    //             this.fields.businessUnitId.option = _.cloneDeep(toJSDeep(this.fields.businessUnitId.option)).concat(data.result);
    //             return data;
    //         });
    // }

    // @action getApp(buId = null){
    //     return adAppPositionController
    //         .getPartnerApps({BUId: buId})
    //         .then((data)=>{
    //             this.fields.appId.option = _.cloneDeep(toJSDeep(this.fields.appId.option)).concat(data.result);
    //             return data;
    //         });
    // }

    // @action getPlatForm(buId = null,appId = null){
    //     return adAppPositionController
    //         .getPartnerAppPlatforms({BUId: buId, appId: appId})
    //         .then((data)=>{
    //             this.fields.platform.option = _.cloneDeep(toJSDeep(this.fields.platform.option)).concat(data.result);
    //             return data;
    //         });
    // }

    // @action getPage(buId = null,appId = null,platform = null){
    //     return adAppPositionController
    //         .getPartnerAppPages({BUId: buId, appId: appId, platform: platform})
    //         .then((data)=>{
    //             this.fields.page.option = _.cloneDeep(toJSDeep(this.fields.page.option)).concat(data.result);
    //             return data;
    //         });
    // }

    // @action getPosition(buId = null, appId = null, platform = null, pageId = null){
    //     return adAppPositionController
    //         .getPartnerAppPagePositions({BUId: buId, appId: appId, platform: platform, pageId: pageId})
    //         .then((data)=>{
    //             this.fields.position.option = _.cloneDeep(toJSDeep(this.fields.position.option)).concat(data.result);
    //             return data;
    //         });
    // }

    // @action getMediaType(position = null){
    //     return adAppPositionController
    //         .getMediaType({position: position})
    //         .then((data)=>{
    //             this.fields.mediaType.option = _.cloneDeep(toJSDeep(this.fields.mediaType.option)).concat(data.result);
    //             return data;
    //         });
    // }

    // @action selectBu(){
    //     this.clearApp();
    //     if (_.toString(this.fields.businessUnitId.value) !== '-1') {
    //         return this.getApp(this.fields.businessUnitId.value).then(() => {
    //             this.changeField('appId',{disabled:false})
    //         });
    //     }
    // }

    // @action selectApp(){
    //     this.clearPlatForm();
    //     if (_.toString(this.fields.appId.value) !== '-1') {
    //         return this.getPlatForm(this.fields.businessUnitId.value,this.fields.appId.value).then(() => {
    //             this.changeField('platform',{disabled:false})
    //         });
    //     }
    // }

    // @action selectPlatForm(){
    //     this.clearPage();
    //     if (_.toString(this.fields.platform.value) !== '-1') {
    //         return this.getPage(this.fields.businessUnitId.value,this.fields.appId.value,this.fields.platform.value).then(() => {
    //             this.changeField('page',{disabled:false})
    //         });
    //     }
    // }

    // @action selectPage(){
    //     this.clearPosition();
    //     if (_.toString(this.fields.page.value) !== '-1') {
    //         return this.getPosition(this.fields.businessUnitId.value,this.fields.appId.value,this.fields.platform.value).then(() => {
    //             this.changeField('position',{disabled:false})
    //         });
    //     }
    // }

    // @action selectPosition(){
    //     this.clearMediaType();
    //     if (_.toString(this.fields.position.value) !== '-1') {
    //         return this.getMediaType(this.fields.position.value).then(() => {
    //             this.changeField('mediaType',{disabled:false})
    //         });
    //     }
    // }

    // @action selectmediatype(value){
    //     this.changeFields(_.mapValues(_.invert(mediaTypeToContent),()=>{
    //         return  {ignore: true, value: ''}
    //     }));

    //     this.changeField(mediaTypeToContent[value],{ignore: false});
    //     this.valid(mediaTypeToContent[value],'',!this.fields[mediaTypeToContent[value]].required);
    // }

    // @action clearBu(){
    //     this.clearApp();
    //     this.clearCommon('businessUnitId');
    // }

    // @action clearApp(){
    //     this.clearPlatForm();
    //     this.clearCommon('appId');
    // }

    // @action clearPlatForm(){
    //     this.clearPage();
    //     this.clearCommon('platform');
    // }

    // @action clearPage(){
    //     this.clearPosition();
    //     this.clearCommon('page');
    // }

    // @action clearPosition(){
    //     this.clearMediaType();
    //     this.clearCommon('position');
    // }

    // @action clearMediaType(){
    //     this.clearCommon('mediaType');
    // }

    // @action clearSelectAll(){
    //     this.clearBu();
    //     this.clearApp();
    //     this.clearPlatForm();
    //     this.clearPage();
    //     this.clearPosition();
    //     this.clearMediaType();
    // }

    // @action bindData(data:AdBean<any>){
    //     this.changeFields({
    //         businessUnitId: { disabled: false },
    //         appId: { disabled: false },
    //         platform: { disabled: false },
    //         page: { disabled: false },
    //         position: {disabled: false},
    //         mediaType: {disabled: false}
    //     })
    //     this.getBu();
    //     this.getApp(data.appId);
    //     this.getPlatForm(data.businessUnitId,data.appId);
    //     this.getPage(data.businessUnitId,data.appId,data.platform);
    //     this.getPosition(data.businessUnitId, data.appId, data.platform, data.page);
    //     this.getMediaType(data.position);
    // }

    @action
    bindData(data: AdBean<any>) {
        this.getMediaType();
    }

    @action
    clearSelect(fieldName) {
        this.fields[fieldName] = _.cloneDeep(this.defaultFields[fieldName]);
        this.valid(fieldName, _.toString(this.fields[fieldName].value));
    }

    /*==================级联菜单结束==========================*/

    getValuesWithName() {
        let me = this,
            data;

        //    let bu, app, platform, page, position, data:AdDto<any>;

        changeContent();

        let filterAreaIds = this.fields.filterAreaIds.value;
        let filterVal = [];

        if (filterAreaIds.length > 0 && _.isNumber(filterAreaIds[0])) {
            filterVal = filterAreaIds;
        } else {
            filterVal = _.map(_.filter(toJSDeep(this.fields.filterAreaIds.value), (item) => {
                return !!item.props && !item.props.hasOwnProperty('children');
            }), (_item) => {
                return _.parseInt(_item.key);
            });
        }


        data = _.assign(this.getValues(), {
            areaIds: filterVal,
            filterAreaIds: []
        });

        return data;

        // bu = findBy('businessUnitId');
        // app = findBy('appId');
        // platform = findBy('platform','type');
        // page = findBy('page');
        // position = findBy('position');

        // return _.assign(data,{
        //     businessUnitName: bu.name,
        //     businessUnitTitle: bu.title,
        //     appName: app.name,
        //     appTitle: app.title,
        //     platformName: platform.name,
        //     platformTitle: platform.title,
        //     pageName: page.name,
        //     pageTitle: page.title,
        //     positionName: position.name,
        //     positionTitle: position.title
        // })

        // function findBy(filedName, key = 'id'){
        //     return _.find(me.fields[filedName].option,function(item){
        //         return _.toString(item[key]) === _.toString(data[filedName]);
        //     }) || {
        //         name: '',
        //         title: ''
        //     };
        // }

        function changeContent() {
            let mediaType = _.toString(me.fields.mediaType.value);
            let content = me.fields[mediaTypeToContent[mediaType]].value;

            me.changeField('content', {value: content});
        }
    }
}

class Add extends AdBaseFormStore {

    defaultFields = _.cloneDeep(addDefaultFields);

    @observable fields: AdField = _.cloneDeep(addDefaultFields);

    @action
    adAdd(params: AdBean<any>) {
        return adService.adAdd(params);
    }

    @action
    load() {
        this.getMediaType();
        this.findTags();
        this.show();
    }
}

class Edit extends AdBaseFormStore {

    defaultFields = _.cloneDeep(editDefaultFields);

    @observable fields: AdField = _.cloneDeep(editDefaultFields);

    @action
    load(id: number) {
        this.findTags();
        return adService.loadEditByAdId({id: id}).then((res) => {
            if (res.success) {
                let data: AdDto<FieldItem> = res.result;
                this.bindData(data);
                this.changeField(mediaTypeToContent[_.toString(data.mediaType)], {ignore: false});
                this.show(_.assign(data, exChangeContent(data), {
                    filterAreaIds: data.areaIds
                }));
            } else {
                message.error(res.message, 3);
            }

            return res;
        })
    }

    @action
    adEdit(params: AdBean<any>) {
        return adService.adEdit(params);
    }
}

class Check extends AdBaseFormStore {
    defaultFields = _.cloneDeep(addDefaultFields);

    @observable fields: AdField = _.cloneDeep(addDefaultFields);

    @observable showTreeData: Array<any> = [];

    @action
    load(id: number) {
        return Promise.all([
            this.findTags(),
            adService.loadEditByAdId({id: id}),
        ]).then(([tags, res]: any) => {
            if (res.success) {
                this.loadShowAreaTree(res.result.areaIds);
                this.getAdapiUrlById({id: id});
                this.show(res.result);
            } else {
                message.error(res.message, 3);
            }
            return res;
        })
    }

    @action
    loadShowAreaTree(areaIds) {
        loadArea().then((data) => {
            this.showTreeData = treeFormatNode.getTreeNode(this.formatAreaTreeData(areaIds, data));
        })
    }

    formatAreaTreeData(areaIds = [], treeData = []) {

        let areaIdsMap = _.map(areaIds, function (item) {
            return _.find(treeData, function (area) {
                return area.id === item;
            })
        });

        return _.filter(treeData, function (item) {
            let treePathArray = item.treePath.split(',');
            return _.some(areaIdsMap, function (area) {
                return _.difference(treePathArray, area.treePath.split(',')).length === 0;
            })
        });
    }
}

class List extends ListStore<AdBean<any>> {
    @observable apiModalVisible: boolean = false;
    @observable apiUrl: Array<string> = [];
    @observable adPositionInfo: Array<any> = []; //广告位信息
    @observable expandedRows: Array<string> = []; //展开的列表

    @action
    getPositionInfosById(params) {
        return adService.getPositionInfosById(params).then((data) => {
            if (data.success) {
                this.adPositionInfo = data.result;
            } else {
                message.error(data.message, 3);
            }

            return data;
        })
    }

    @action
    changeTableData(fieldName, data) {
        this[fieldName] = data;
    }

    @action
    getAdapiUrlById(params) {
        return adService.getAdapiUrlById(params).then((data) => {
            if (data.success) {
                this.apiUrl = data.result;
            } else {
                message.error(data.message, 3);
            }

            return data;
        })
    }

    @action
    searchAd(params?: any) {
        this._SpiLoading = true;

        adService.searchAdList(params).then((data) => {
            this.searchCallback(data);
        })
    }

    @action
    delete(id: number) {
        return adService.adDelete({id: id});
    }

    @action
    load(params: any = {}) {
        this.expandedRows = [];
        this.searchAd(params);
    }

    @action
    refresh(search: Search) {
        this.expandedRows = [];
        this.changeState(true);
        search.clearAll();
        this.load();
    }

    @action
    showApi() {
        this.apiModalVisible = true;
    }

    @action
    hideApi() {
        this.apiModalVisible = false;
    }
}

class AreaTreeStore {
    constructor() {
        this.loadAreaTree();
    }

    treeData: Array<any> = [];

    loadAreaTree() {
        loadArea().then((data) => {
            this.treeData = treeFormatNode.getTreeNode(data);
        })
    }
}

const searchDefaultFields = toPlainObjectDeep(new AdSearchField());

class Search extends FormStore<AdSearchField, AdSearchBean<any>> {

    defaultFields = _.cloneDeep(searchDefaultFields);

    @observable fields: AdSearchField = _.cloneDeep(searchDefaultFields);

    @observable expand: boolean = false;

    @action
    OnExpand(expand) {
        this.expand = !expand;
    }

    @action
    clearSearch(list: List) {
        this.clearAll();
        list.load();
    }

    @action
    clearSearchState() {
        this.expand = false;
        this.clearAll();
    }

    getSearchValues() {
        const format = "YYYY-MM-DD HH:mm:ss";
        let data: AdSearchBean<any> = this.getValues();

        return _.assign(data, {
            beginDate: data.beginDate ? data.beginDate.format(format) : null,
            endDate: data.endDate ? data.endDate.format(format) : null
        })
    }
}

const bindMediaTypeDefaultFields = toPlainObjectDeep(new AdBindMediaTypeField());

export class AdBindMediaType extends FormStore<AdBindMediaTypeField, AdBindBean<any>> {

    defaultFields = _.cloneDeep(bindMediaTypeDefaultFields);

    validators = {
        adPositionIds: [isRequired]
    }

    @observable confirmLoading: boolean = false;

    @observable fields: AdBindMediaTypeField = _.cloneDeep(bindMediaTypeDefaultFields);

    @action
    changeConfirmLoading(params) {
        this.confirmLoading = params;
    }

    @action
    load(record) {
        let data = {
            id: _.parseInt(record.id),
            title: record.title,
            mediaType: mediaTypeToText[record.mediaType],
            adPositionIds: _.map(record.adPositionIds, _.toString)
        }
        this.getPosition(_.parseInt(record.mediaType));
        this.show(data);
    }

    @action
    update(params) {
        return adService.bindPositionByMediaType(params);
    }

    /*====================获取广告位信息==========================*/
    @action
    getPosition(type = null) {
        return adService
            .getPositionByMediaType({type: type})
            .then((data) => {
                this.fields.adPositionIds.option = _.cloneDeep(toJSDeep(this.fields.adPositionIds.option)).concat(data.result);
                return data;
            });
    }
}

function exChangeContent(res: AdBean<any>): AdDto<AdField> {
    let data: any = {};

    data[mediaTypeToContent[_.toString(res.mediaType)]] = res.content;

    if (!!res.beginDate && !!res.endDate) {
        data.time = [moment(res.beginDate), moment(res.endDate)];
    } else {
        data.time = null;
    }

    return data;
}

export const listStore = new List();
export const addStore = new Add();
export const editStore = new Edit();
export const checkStore = new Check();
export const areaTreeStore = new AreaTreeStore();
export const searchStore = new Search();
export const adBindMediaTypeStore = new AdBindMediaType();